home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / think / AmigaGnuChess.lha / chess / src.lha / src / genmoves.c < prev    next >
C/C++ Source or Header  |  1992-09-01  |  10KB  |  347 lines

  1. /*
  2.  * genmoves.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. short *TrP;
  25.  
  26. #define Link(from,to,flag,s) \
  27. {\
  28.    node->f = from; node->t = to;\
  29.      node->reply = 0;\
  30.        node->flags = flag;\
  31.      node->score = s;\
  32.        ++node;\
  33.          *TrP += 1;\
  34.          }
  35.  
  36. inline void
  37. LinkMove (short int ply, short int f,
  38.       short int t,
  39.       short int flag,
  40.       short int xside)
  41.  
  42. /*
  43.  * Add a move to the tree.  Assign a bonus to order the moves as follows: 1.
  44.  * Principle variation 2. Capture of last moved piece 3. Other captures
  45.  * (major pieces first) 4. Killer moves 5.
  46.  */
  47.  
  48. {
  49.   register short s = 0;
  50. #if defined HISTORY
  51.   register short z;
  52. #endif
  53.   register unsigned short mv;
  54.   register struct leaf *node;
  55.  
  56.   node = &Tree[*TrP];
  57.   mv = (f << 8) | t;
  58. #ifdef KILLT
  59.   s = killt[mv | sidebit];
  60. #endif
  61. #ifdef HISTORY
  62.   z = mv;
  63.   if (xside == white) z |= 0x4000;
  64.   s = history[z];
  65. #endif
  66.   if (color[t] != neutral)
  67.     {
  68.       /* TOsquare is the square the last piece moved moved to */
  69.       s += value[board[t]] - board[f] + ((t == TOsquare) ? 500 : 0);
  70.     }
  71.   if (board[f] == pawn)
  72.     if (row (t) == 0 || row (t) == 7)
  73.       {
  74.     flag |= promote;
  75.     s += 800;
  76. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  77.     Link (f, t, flag | queen, s - 20000);
  78.     s -= 200;
  79.     Link (f, t, flag | knight, s - 20000);
  80.     s -= 50;
  81.     Link (f, t, flag | rook, s - 20000);
  82.     flag |= bishop;
  83.     s -= 50;
  84. #else
  85.     flag |= queen;
  86. #endif
  87.       }
  88.     else if (row (t) == 1 || row (t) == 6)
  89.       {
  90.     flag |= pwnthrt;
  91.     s += 600;
  92.       }
  93.     else if ((row (t) == 2 || row (t) == 5) && (ply > MINDEPTH) && (ply < Sdepth+3))
  94.       {
  95.     if ((mtl[white] - pmtl[white] + mtl[black] - pmtl[black]) < PTVALUE)
  96.       {
  97.         flag |= pwnthrt;
  98.         s += 400;
  99.       }
  100.       }
  101.   Link (f, t, flag, s - 20000);
  102. }
  103.  
  104. inline
  105. void
  106. GenMoves (register short int ply, register short int sq, short int side, short int xside)
  107.  
  108. /*
  109.  * Generate moves for a piece. The moves are taken from the precalulated
  110.  * array nextpos/nextdir. If the board is free, next move is choosen from
  111.  * nextpos else from nextdir.
  112.  */
  113.  
  114. {
  115.   register short u, piece;
  116.   register unsigned char *ppos, *pdir;
  117.  
  118.   TrP = &TrPnt[ply + 1];
  119.   piece = board[sq];
  120.   ppos = nextpos[ptype[side][piece]][sq];
  121.   pdir = nextdir[ptype[side][piece]][sq];
  122.   if (piece == pawn)
  123.     {
  124.       u = ppos[sq];        /* follow no captures thread */
  125.       if (color[u] == neutral)
  126.     {
  127.       LinkMove (ply, sq, u, 0, xside);
  128.       u = ppos[u];
  129.       if (color[u] == neutral)
  130.         LinkMove (ply, sq, u, 0, xside);
  131.     }
  132.       u = pdir[sq];        /* follow captures thread */
  133.       if (color[u] == xside)
  134.     LinkMove (ply, sq, u, capture, xside);
  135.       u = pdir[u];
  136.       if (color[u] == xside)
  137.     LinkMove (ply, sq, u, capture, xside);
  138.     }
  139.   else
  140.     {
  141.       u = ppos[sq];
  142.       do
  143.     {
  144.       if (color[u] == neutral)
  145.         {
  146.           LinkMove (ply, sq, u, 0, xside);
  147.           u = ppos[u];
  148.         }
  149.       else
  150.         {
  151.           if (color[u] == xside)
  152.         LinkMove (ply, sq, u, capture, xside);
  153.           u = pdir[u];
  154.         }
  155.       } while (u != sq);
  156.     }
  157. }
  158.  
  159. void
  160. MoveList (short int side, register short int ply)
  161.  
  162. /*
  163.  * Fill the array Tree[] with all available moves for side to play. Array
  164.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  165.  */
  166.  
  167. {
  168.   register short i, xside, f;
  169.  
  170.   xside = side ^ 1;
  171.   TrP = &TrPnt[ply + 1];
  172.   *TrP = TrPnt[ply];
  173.   if (!PV)
  174.     Swag0 = killr0[ply];
  175.    else Swag0 = PV;
  176.   Swag1 = killr1[ply];
  177.   Swag2 = killr2[ply];
  178.   Swag3 = killr3[ply];
  179.   if (ply > 2)
  180.     Swag4 = killr1[ply - 2]; else Swag4 = 0;
  181. #ifdef KILLT
  182.   sidebit = ((side == white) ? 0 : 0x80);
  183.   killt[SwagHt | sidebit] += 5000;
  184.   if(SwagHt != Swag0)killt[Swag0 | sidebit] += 2000;
  185.   if(SwagHt != Swag1 && Swag1 != Swag0)killt[Swag1 | sidebit] += 60;
  186.   if(SwagHt != Swag2 && Swag0 != Swag2 && Swag1 != Swag2)killt[Swag2 | sidebit] += 50;
  187.   if(SwagHt != Swag3 && Swag0 != Swag3 && Swag1 != Swag3 && Swag2 != Swag3)killt[Swag3 | sidebit] += 40;
  188.   if(SwagHt != Swag4 && Swag0 != Swag4 && Swag1 != Swag4 && Swag2 != Swag4 && Swag3 != Swag4)killt[Swag4 | sidebit] += 30;
  189. #endif
  190. #ifdef HISTORY
  191.   i = (side == black)?0x4000:0;
  192.   history[SwagHt | i] += 5000;
  193.   if(SwagHt != Swag0)history[Swag0 | i] += 2000;
  194.   if(SwagHt != Swag1 && Swag1 != Swag0)history[Swag1 | i] += 60;
  195.   if(SwagHt != Swag2 && Swag0 != Swag2 && Swag1 != Swag2)history[Swag2 | i] += 50;
  196.   if(SwagHt != Swag3 && Swag0 != Swag3 && Swag1 != Swag3 && Swag2 != Swag3)history[Swag3 | i] += 40;
  197.   if(SwagHt != Swag4 && Swag0 != Swag4 && Swag1 != Swag4 && Swag2 != Swag4 && Swag3 != Swag4)history[Swag4 | i] += 30;
  198. #endif
  199.   for (i = PieceCnt[side]; i >= 0; i--)
  200.     GenMoves (ply, PieceList[side][i], side, xside);
  201.   if (!castld[side])
  202.     {
  203.       f = PieceList[side][0];
  204.       if (castle (side, f, f + 2, 0))
  205.     {
  206.       LinkMove (ply, f, f + 2, cstlmask, xside);
  207.     }
  208.       if (castle (side, f, f - 2, 0))
  209.     {
  210.       LinkMove (ply, f, f - 2, cstlmask, xside);
  211.     }
  212.     }
  213.   if (epsquare > 0)
  214.     {
  215.       f = epmove1[epsquare];
  216.       if (color[f] == side && board[f] == pawn)
  217.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  218.       f = epmove2[epsquare];
  219.       if (color[f] == side && board[f] == pawn)
  220.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  221.     }
  222. #ifdef KILLT
  223.   killt[SwagHt | sidebit] -= 5000;
  224.   if(SwagHt != Swag0)killt[Swag0 | sidebit] -= 2000;
  225.   if(SwagHt != Swag1 && Swag1 != Swag0)killt[Swag1 | sidebit] -= 60;
  226.   if(SwagHt != Swag2 && Swag0 != Swag2 && Swag1 != Swag2)killt[Swag2 | sidebit] -= 50;
  227.   if(SwagHt != Swag3 && Swag0 != Swag3 && Swag1 != Swag3 && Swag2 != Swag3)killt[Swag3 | sidebit] -= 40;
  228.   if(SwagHt != Swag4 && Swag0 != Swag4 && Swag1 != Swag4 && Swag2 != Swag4 && Swag3 != Swag4)killt[Swag4 | sidebit] -= 30;
  229. #endif
  230. #ifdef HISTORY
  231.  i = (side == black)?0x4000:0;
  232.   history[SwagHt | i] -= 5000;
  233.   if(SwagHt != Swag0)history[Swag0 | i] -= 2000;
  234.   if(SwagHt != Swag1 && Swag1 != Swag0)history[Swag1 | i] -= 60;
  235.   if(SwagHt != Swag2 && Swag0 != Swag2 && Swag1 != Swag2)history[Swag2 | i] -= 50;
  236.   if(SwagHt != Swag3 && Swag0 != Swag3 && Swag1 != Swag3 && Swag2 != Swag3)history[Swag3 | i] -= 40;
  237.   if(SwagHt != Swag4 && Swag0 != Swag4 && Swag1 != Swag4 && Swag2 != Swag4 && Swag3 != Swag4)history[Swag4 | i] -= 30;
  238. #endif
  239.   SwagHt = 0;            /* SwagHt is only used once */
  240. }
  241.  
  242. void
  243. CaptureList (register short int side, short int ply)
  244.  
  245. /*
  246.  * Fill the array Tree[] with all available cature and promote moves for side
  247.  * to play. Array TrPnt[ply] contains the index into Tree[] of the first move
  248.  * at a ply.
  249.  */
  250.  
  251. {
  252.   register short u, sq, xside;
  253.   register struct leaf *node;
  254.   register unsigned char *ppos, *pdir;
  255.   short i, piece, *PL, r7;
  256.  
  257.   xside = side ^ 1;
  258.   TrP = &TrPnt[ply + 1];
  259.   *TrP = TrPnt[ply];
  260.   node = &Tree[*TrP];
  261.   r7 = rank7[side];
  262.   PL = PieceList[side];
  263. #ifdef KILLT
  264.   sidebit = ((side == white) ? 0 : 0x80);
  265.   killt[SwagHt | sidebit] += 5000;
  266.   if(SwagHt != Swag0)killt[Swag0 | sidebit] += 2000;
  267.   if(SwagHt != Swag1 && Swag1 != Swag0)killt[Swag1 | sidebit] += 60;
  268.   if(SwagHt != Swag2 && Swag0 != Swag2 && Swag1 != Swag2)killt[Swag2 | sidebit] += 50;
  269.   if(SwagHt != Swag3 && Swag0 != Swag3 && Swag1 != Swag3 && Swag2 != Swag3)killt[Swag3 | sidebit] += 40;
  270.   if(SwagHt != Swag4 && Swag0 != Swag4 && Swag1 != Swag4 && Swag2 != Swag4 && Swag3 != Swag4)killt[Swag4 | sidebit] += 30;
  271. #endif
  272.  
  273.   for (i = 0; i <= PieceCnt[side]; i++)
  274.     {
  275.       sq = PL[i];
  276.       piece = board[sq];
  277.       if (sweep[piece])
  278.     {
  279.       ppos = nextpos[piece][sq];
  280.       pdir = nextdir[piece][sq];
  281.       u = ppos[sq];
  282.       do
  283.         {
  284.           if (color[u] == neutral)
  285.         u = ppos[u];
  286.           else
  287.         {
  288.           if (color[u] == xside)
  289.             Link (sq, u, capture, value[board[u]] + svalue[board[u]] - piece);
  290.           u = pdir[u];
  291.         }
  292.       } while (u != sq);
  293.     }
  294.       else
  295.     {
  296.       pdir = nextdir[ptype[side][piece]][sq];
  297.       if (piece == pawn && row (sq) == r7)
  298.         {
  299.           u = pdir[sq];
  300.           if (color[u] == xside)
  301.         Link (sq, u, capture | promote | queen, valueQ);
  302.           u = pdir[u];
  303.           if (color[u] == xside)
  304.         {
  305.           Link (sq, u, capture | promote | queen, valueQ);
  306. #if defined OLDXBOARD  || defined GNU3 || defined CHESSTOO
  307.           Link (sq, u, promote | knight, valueN);
  308.           Link (sq, u, promote | rook, valueR);
  309.           Link (sq, u, promote | bishop, valueB);
  310. #endif
  311.         }
  312.           ppos = nextpos[ptype[side][piece]][sq];
  313.           u = ppos[sq];    /* also generate non capture promote */
  314.           if (color[u] == neutral)
  315.         {
  316.           Link (sq, u, promote | queen, valueQ);
  317. #if defined OLDXBOARD  || defined GNU3 || defined CHESSTOO
  318.           Link (sq, u, promote | knight, valueN);
  319.           Link (sq, u, promote | rook, valueR);
  320.           Link (sq, u, promote | bishop, valueB);
  321. #endif
  322.         }
  323.         }
  324.       else
  325.         {
  326.           u = pdir[sq];
  327.           do
  328.         {
  329.           if (color[u] == xside)
  330.             Link (sq, u, capture, value[board[u]] + svalue[board[u]] - piece);
  331.           u = pdir[u];
  332.           } while (u != sq);
  333.         }
  334.     }
  335.     }
  336. #ifdef KILLT
  337.   sidebit = ((side == white) ? 0 : 0x80);
  338.   killt[SwagHt | sidebit] -= 5000;
  339.   if(SwagHt != Swag0)killt[Swag0 | sidebit] -= 2000;
  340.   if(SwagHt != Swag1 && Swag1 != Swag0)killt[Swag1 | sidebit] -= 60;
  341.   if(SwagHt != Swag2 && Swag0 != Swag2 && Swag1 != Swag2)killt[Swag2 | sidebit] -= 50;
  342.   if(SwagHt != Swag3 && Swag0 != Swag3 && Swag1 != Swag3 && Swag2 != Swag3)killt[Swag3 | sidebit] -= 40;
  343.   if(SwagHt != Swag4 && Swag0 != Swag4 && Swag1 != Swag4 && Swag2 != Swag4 && Swag3 != Swag4)killt[Swag4 | sidebit] -= 30;
  344. #endif
  345.   SwagHt = 0;            /* SwagHt is only used once */
  346. }
  347.